package util

import (
	"cloud.hubbleye.appalert.service_r/internal/middleware"
	"cloud.hubbleye.appalert.service_r/internal/model"
	"encoding/json"
	"github.com/nsqio/go-nsq"
	"go.uber.org/zap"
	"log"
	"strings"
	"time"
)

var (
	ExcludeTopics = []string{"sucker", "hubbleye", "tentacle", "registry"}
	LogType       = "span"
)

// 消费者
type ConsumerT struct{}

// 主函数
func HanderNsq(address []string) {
	InitConsumer("application-log", "judge_k8s", address)
	for {
		time.Sleep(time.Second * 10)
	}
}

//处理消息
func (h *ConsumerT) HandleMessage(message *nsq.Message) error {
	var req = []model.Applog{}
	err := json.Unmarshal(message.Body, &req)
	if err != nil {
		log.Println(err.Error())
		message.Requeue(time.Second * 2)
		return nil
	}
	var alertEvets []*model.AlertEvent
	for i := 0; i < len(req); i++ {
		if req[i].Level >= 3 {
			if ExistsIgnoreCase(ExcludeTopics, req[i].Topic) {
				continue
			}
			if req[i].LogType == LogType {
				continue
			}
			var alertEvent = buildAlertEvent(&req[i])
			alertEvets = append(alertEvets, alertEvent)
		}
	}
	if len(alertEvets) > 0 {
		//发送告警中心
		err = Alert(alertEvets)
		//fmt.Println("NSQL->alertEvent", alertEvets)
		if err != nil {
			log.Println(err.Error())
			middleware.Logger.Info("NSQ HandleMessage  error",
				zap.String("error_message->", err.Error()),
			)
		}
	}
	message.Finish()
	return nil
}

//初始化消费者
func InitConsumer(topic string, channel string, address []string) {
	cfg := nsq.NewConfig()
	cfg.LookupdPollInterval = time.Second          //设置重连时间
	c, err := nsq.NewConsumer(topic, channel, cfg) // 新建一个消费者
	if err != nil {
		panic(err)
	}
	c.SetLogger(nil, 0)        //屏蔽系统日志
	c.AddHandler(&ConsumerT{}) // 添加消费者接口
	if err := c.ConnectToNSQLookupds(address); err != nil {
		panic(err)
	}
}

func buildAlertEvent(applog *model.Applog) *model.AlertEvent {
	var event = &model.AlertEvent{
		SystemAlias:         applog.SystemAlias,
		Env:                 "prd",
		EventDatasource:     "app",
		EventDatasourceName: "应用告警",
		EventOccurTimestamp: applog.Timestamp / 1000000,
		EventOccurIp:        applog.InstanceId,
		AlertContent:        applog.Content,
		AlertPhrase:         applog.Content,
		EventLayer:          "1",
		EventCategory:       "logError",
		EventId:             applog.TraceId,
		TargetSystemAlias:   applog.RemoteSystemAlias,
		TargetIP:            applog.RemoteIpAddress,
	}
	return event
}

func ExistsIgnoreCase(set []string, find string) bool {
	find = strings.ToLower(find)
	for _, s := range set {
		if strings.ToLower(s) == find {
			return true
		}
	}
	return false
}
